//
//  KLHttpRequest.m
//  KoalaUtilKit
//
//  Created by Tommy on 15/1/7.
//  Copyright (c) 2015年 Koala Team. All rights reserved.
//

#import "KLHttpRequest.h"
#import "KLTransformer.h"
#import "KLModel.h"
#import "KLLog.h"
#import "KLError.h"
#import "KLJsonToModelTransformer.h"

typedef void (^KLHttpProgressBlock)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite);

static AFHTTPRequestOperationManager *httpMgr;
@interface KLHttpRequest()


@end


@implementation KLHttpRequest

+(void)initialize{
    httpMgr = [AFHTTPRequestOperationManager manager];
}


- (instancetype)initWithWithPath:(NSString*)path params:(NSDictionary*)params withTransformer:(id<KLITransformer>)transformer {
    if(self = [super initWithTransformer:transformer andRequestBlock:nil]){
        _path = path;
    }
    return self;
}

+ (RACSignal *)sendHttpRequestWithPath:(NSString*)path parameters:(id)parameters toModel:(Class)modelCls{
    KLJsonToModelTransformer *transformer = [KLJsonToModelTransformer transformerWithModel:modelCls];
    return [[[KLHttpRequest alloc]initWithWithPath:path params:parameters withTransformer:transformer] startRequest];
}

- (RACSignal*)startRequest{
    @weakify(self);
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        @strongify(self);
        self.executing = YES;
        self.finished = NO;
        AFHTTPRequestOperationManager* mgr = httpMgr;
        RACDisposable *dispose = [[[[mgr rac_GET:self.path parameters:self.params] flattenMap:^RACStream *(id value) {
            self.response = value;
            return self.transformer?[self.transformer transform:self.response]:[RACSignal return:self.response];
        }] finally:^{
            self.executing = NO;
            self.finished = YES;
        }] subscribeNext:^(id x) {
            [subscriber sendNext:x];
        } error:^(NSError *error) {
            self.error = error;
            [subscriber sendError:error];
        }];
        
        [RACObserve(self, isCancelled) subscribeNext:^(NSNumber *canceled) {
            if([canceled boolValue]){
                [dispose dispose];
            }
        }];

        return dispose;
    }];
}


@end
